﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using PulmonaryFunctionLib;

namespace TestWPF
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private ConcurrentQueue<double> m_dataQueue = new ConcurrentQueue<double>(); // 数据队列
        private DispatcherTimer timer = new DispatcherTimer();
        private readonly int REFRESH_FPS = 2; // 帧率
        private CylinderProgress progress = new CylinderProgress(0);
        private bool start = false;
        private double calVolume = 1;
        private double inVolume = 0;
        /* 采样率,单位:HZ */
        public readonly double SAMPLE_RATE = 330;
        /* 采样时间,单位:MS */
        public double SAMPLE_TIME { get { return (1000 / SAMPLE_RATE); } }

        private FlowValidator flowValidator = new FlowValidator(330, 1);

        public MainWindow()
        {
            InitializeComponent();

            /* 采样开始 */
            flowValidator.SampleStarted += new FlowValidator.SampleStartHandler((uint flowIndex, FlowValidator.RespireDirection direction) =>
            {
                Console.WriteLine($"SampleStarted: {flowIndex} {direction}");

                progress.IsInspiration = (direction == FlowValidator.RespireDirection.Inspiration);
            });

            /* 采样结束 */
            flowValidator.SampleStoped += new FlowValidator.SampleStopHandler((uint flowIndex, FlowValidator.RespireDirection direction, uint sampleIndex) =>
            {
                Console.WriteLine($"SampleStoped: {flowIndex} {direction} {sampleIndex}");

                flowValidator.Reset();
            });

            this.DataContext = progress;

            timer.Interval = TimeSpan.FromMilliseconds(REFRESH_FPS);
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        /* 已接收到一个流量采集数据 */
        private void OnFlowRecved(double flow)
        {
            inVolume += flow * (SAMPLE_TIME / 1000);
            if (inVolume < 0) 
                inVolume = 0;
            else if (inVolume > calVolume) 
                inVolume = calVolume;
            double pr = inVolume * 100 / calVolume;
            //Console.WriteLine(pr);
            progress.Progress = pr;

            flowValidator.Input(flow);
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // 尝试读取队列中的数据并添加到曲线
            while (m_dataQueue.Count > 0)
            {
                /* 尝试读取队列中的数 */
                bool bRet = m_dataQueue.TryDequeue(out double flow); // 流量
                if (!bRet)
                {
                    break;
                }

                /* 已接收到一个流量采集数据 */
                OnFlowRecved(flow);
            }
        }

        //"../../data/calibbration_20200315_090307.csv"
        private async Task LoadCSVFileAsync(string filePath)
        {
            /* 启动任务执行异步加载(防止阻塞UI线程) */
            Task loadTask = Task.Factory.StartNew((Action)(() =>
            {
                try
                {
                    /* 所有数据先加载到内存 */
                    string strData = string.Empty;
                    using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
                    {
                        strData = reader.ReadToEnd();
                        reader.Close();
                    }

                    /* 解析CSV中的流量数据 */
                    string[] strDataArray = strData.Split(new char[] { ',' });
                    foreach (var strVal in strDataArray)
                    {
                        if (string.Empty == strVal)
                        {
                            continue;
                        }

                        double flow = Convert.ToDouble(strVal); // 流量

                        /* 数据存入队列,将在刷新定时器中读取 */
#if false
                        m_dataQueue.Enqueue(flow);
#else
                        this.Dispatcher.Invoke(() =>
                        {
                            OnFlowRecved(flow);
                        });
#endif

                        /* 模拟采样率 */
                        Thread.Sleep((int)SAMPLE_TIME);
                    }
                    /* 数据已加载完毕 */
                }
                catch (Exception e)
                {
                    MessageBox.Show($"加载失败!{e.ToString()}");
                }
            }));

            await loadTask; // 等待加载完毕
        }

        private async void startBtn_Click(object sender, RoutedEventArgs e)
        {
            if (start)
            {
                return;
            }
            start = true;
            flowValidator.Clear();
            await LoadCSVFileAsync("../../data/flow.csv");
        }
    }
}
